import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { isArray, isNull, isRegExp } from './checkType';
dayjs.extend(utc);

export const deepClone = function deepClone(target: any) {
  let result: any;
  // 如果当前需要深拷贝的是一个对象的话
  if (typeof target === 'object') {
    // 如果是一个数组的话
    if (isArray(target)) {
      result = []; // 将result赋值为一个数组，并且执行遍历
      for (let i in target) {
        if (target.hasOwnProperty(i)) {
          // 递归克隆数组中的每一项
          result.push(deepClone(target[i]));
        }
      }
      // 判断如果当前的值是null的话；直接赋值为null
    } else if (isNull(target)) {
      result = null;
      // 判断如果当前的值是一个RegExp对象的话，直接赋值
    } else if (isRegExp(target)) {
      result = target;
    } else {
      // 否则是普通对象，直接for in循环，递归赋值对象的所有值
      result = {};
      for (let i in target) {
        if (target.hasOwnProperty(i)) {
          result[i] = deepClone(target[i]);
        }
      }
    }
    // 如果不是对象的话，就是基本数据类型，那么直接赋值
  } else {
    result = target;
  }

  return result;
};

export function formatToTreeArr<T extends Record<string, any>>(source: Requestor.SourceTree<T>[]) {
  const sourceData: Requestor.SourceTree<T>[] = deepClone(source);
  const data: Record<string, any> = sourceData.reduce((result, item) => {
    result[item.id] = item;
    return result;
  }, {} as Record<string, any>);
  const arr: Requestor.TargetTree<T>[] = [];
  sourceData.forEach((item) => {
    const parentId = item.parentID || item.parentId || '';
    const curItemParent = data[parentId];

    if (curItemParent) {
      curItemParent.children = curItemParent.children || [];
      curItemParent.children.push(Object.assign(item, { key: item.id }));
    } else {
      arr.push(Object.assign(item, { key: item.id }));
    }
  });
  return arr;
}
export function formatToSelectTreeArr<T extends Record<string, any>>(
  source: Requestor.SourceTree<T>[],
  labelKey: string,
) {
  const sourceData: Requestor.SourceTree<T>[] = deepClone(source);
  const data: Record<string, any> = sourceData.reduce((result, item) => {
    result[item.id] = item;
    return result;
  }, {} as Record<string, any>);
  const arr: Requestor.SelectTargetTree<T>[] = [];
  sourceData.forEach((item) => {
    const parentId = item.parentID || item.parentId || '';
    const curItemParent = data[parentId];

    if (curItemParent) {
      curItemParent.children = curItemParent.children || [];
      curItemParent.children.push(
        Object.assign(item, { key: item.id, value: item.id, title: item[labelKey] }),
      );
    } else {
      arr.push(Object.assign(item, { key: item.id, value: item.id, title: item[labelKey] }));
    }
  });
  return arr;
}
export function getParentTree<T extends Record<string, any>>(
  treeData: Requestor.TargetTree<T>[],
  key: string,
) {
  let t: Requestor.TargetTree<T>[] = [];
  for (let i = 0; i < treeData.length; i++) {
    const e = treeData[i];
    if (e.key === key) {
      //若查询到对应的节点，则直接返回
      t.push(e);
      break;
    } else if (e.children && e.children.length !== 0) {
      //判断是否还有子节点，若有对子节点进行循环调用
      let p = getParentTree(e.children, key);
      //若p的长度不为0，则说明子节点在该节点的children内，记录此节点，并终止循环
      if (p.length !== 0) {
        p.unshift(e);
        t = p;
        break;
      }
    }
  }
  return t;
}
export function findTreeData<T extends Record<string, any>>(
  treeData: Requestor.TargetTree<T>[],
  key: string,
) {
  let t: Requestor.TargetTree<T>[] = [];
  for (let i = 0; i < treeData.length; i++) {
    const e = treeData[i];
    if (e.key === key) {
      t.push(e);
      break;
    } else if (e.children && e.children.length !== 0) {
      t = findTreeData(e.children, key);
    }
  }
  return t;
}
/** 获取tree data 下所有的keys */
export function getTreeDataKeys<T extends Record<string, any>>(
  treeData: Requestor.TargetTree<T>[],
  result: string[] = [],
  key = 'key',
) {
  for (let i = 0; i < treeData.length; i++) {
    const e = treeData[i];
    result.push(e[key]);
    if (e.children && e.children.length !== 0) {
      getTreeDataKeys(e.children, result);
    }
  }
  return result;
}
export function formatUTCTime(time: string) {
  return dayjs(time).utc().format();
}
export default {
  deepClone,
  formatToTreeArr,
  formatToSelectTreeArr,
  getTreeDataKeys,
  formatUTCTime,
};
